﻿using System.Windows;
using System.Windows.Controls;
using ZoomTextBoxPhone.Input;

namespace ZoomTextBoxPhone
{
    public class ZoomTextBoxControl : TextBox
    {

        private double _originalSize;
        private double _tick;

        public ZoomTextBoxControl()
        {
            DefaultStyleKey = typeof(ZoomTextBoxControl);
            Loaded += ZoomTextBoxControlLoaded;
        }

        private void ZoomTextBoxControlLoaded(object sender, RoutedEventArgs e)
        {
            GestureService.GetGestureListener(this).PinchDelta += GestureListenerPinchDelta;
        }

        public static readonly DependencyProperty ZoomStepsProperty =
                DependencyProperty.Register("ZoomSteps", typeof(int), typeof(ZoomTextBoxControl),
                                new PropertyMetadata(int.Parse("35"), null));

        public int ZoomSteps
        {
            get { return (int)GetValue(ZoomStepsProperty); }
            set {
                if (value < 1)
                {
                    value = 1;
                }
                SetValue(ZoomStepsProperty, value);
            }
        }


        public static readonly DependencyProperty CurrentZoomStepProperty =
                DependencyProperty.Register("CurrentZoomStep", typeof(int), typeof(ZoomTextBoxControl),
                                new PropertyMetadata(int.Parse("0"), null));

        public int CurrentZoomStep
        {
            get { return (int)GetValue(CurrentZoomStepProperty); }
            set
            {
                if (value < 0)
                {
                    value = 0;
                }
                if (value > ZoomSteps)
                {
                    value = ZoomSteps;
                }
                SetValue(CurrentZoomStepProperty, value);
                ZoomChange(value);
            }
        }

        public static readonly DependencyProperty ZoomMaxSizeProperty =
                DependencyProperty.Register("ZoomMaxSize", typeof(double), typeof(ZoomTextBoxControl),
                                new PropertyMetadata(double.Parse("0"), null));

        public double ZoomMaxSize
        {
            get { return (double)GetValue(ZoomMaxSizeProperty); }
            set { SetValue(ZoomMaxSizeProperty, value); }
        }

        private void Zoom(bool zoomOut)
        {
            if (zoomOut && CurrentZoomStep + 1 <= ZoomSteps)
            {
                ZoomChange(CurrentZoomStep+1);
            }
            if (!zoomOut && CurrentZoomStep - 1 >=0)
            {
                ZoomChange(CurrentZoomStep-1);
                
            }
        }

        public void ZoomMax()
        {
            ZoomChange(ZoomSteps-1);
        }

        public void ZoomReset()
        {
            ZoomChange(0);
        }

        private void GestureListenerPinchDelta(object sender, PinchGestureEventArgs e)
        {
            if (!IsEnabled)
            {
                return;
            }
            if (e.DistanceRatio.Equals(1.0))
            {
                return;
            }
            Zoom(e.DistanceRatio > 1.0);
        }

        private void EnsureProperties()
        {
            if (_originalSize.Equals(0))
            {
                _originalSize = FontSize;
                if (ZoomMaxSize <= _originalSize && !ZoomMaxSize.Equals(0))
                {
                    ZoomMaxSize = _originalSize;
                }
            }
            if (ZoomMaxSize.Equals(0))
            {
                ZoomMaxSize = FontSize * 4;
            }
            _tick = (ZoomMaxSize-_originalSize) / ZoomSteps;
        }

        private void ZoomChange(int step)
        {
            EnsureProperties();
            var newfnt = _originalSize + (_tick * step);
            if (newfnt > ZoomMaxSize)
            {
                newfnt = ZoomMaxSize;
                SetValue(CurrentZoomStepProperty, ZoomSteps);
            }
            else
            {
                SetValue(CurrentZoomStepProperty, step);
            }
            FontSize = newfnt;
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            IsEnabledChanged += delegate
            {
                ChangeEnabled();
            };
            ChangeEnabled();
        }

        private void ChangeEnabled()
        {
            if (!IsEnabled)
            {
                if (_originalSize.Equals(0))
                {
                    _originalSize = FontSize;
                }
                FontSize = _originalSize;
            }
        }

    }
}